package main

import (
	"context"
	"encoding/json"
	_ "github.com/go-sql-driver/mysql"
	"go-websocket/database"
	websocketError "go-websocket/error"
	"go-websocket/model"
	"go-websocket/server"
	"go-websocket/users"
	"log"
	"net/http"
	"nhooyr.io/websocket"
	"time"
)

const (
	username = "root1"
	password = "root1"
	databaseName = "websocket"
)

type RequestMessage struct {
	// id
	Uid string `json:"uid"`
	// 机构id
	Gid string `json:"gid"`
	// 问题组id
	Qid string `json:"qid"`
	// 发送人id
	SenderId int `json:"sender_id"`
	// 接收人id
	ReceiverId int `json:"receiver_id"`
	// 接收者类型
	ReceiverType uint8 `json:"receiver_type"`
	// 消息内容
	Content string `json:"content"`
	// 发送时间
	SendTime time.Time `json:"send_time"`
}

func main()  {
	// 开启数据库连接
	err := database.DbStart(username, password, databaseName)
	if err != nil {
		panic(err)
	}
	// 开启用户管理器
	users.NewUsersServer()
	// 开启错误管理器
	websocketError.NewErrorsManage()
	// 开启 http 设置
	http.HandleFunc("/ws", func(writer http.ResponseWriter, request *http.Request) {
		// 接受websocket 对象
		conn, err := websocket.Accept(writer, request, &websocket.AcceptOptions{
			InsecureSkipVerify:   true,
		})
		if err != nil {
			log.Fatalln(err)
			return
		}
		// 开启协程处理处理客户信息
		go func(conn *websocket.Conn) {
			// 关闭链接
			defer conn.Close(websocket.StatusInternalError, "")
			for {
				ctx := context.Background()
				ctx, cancel := context.WithCancel(ctx)
				// 阻塞读取用户消息
				_, content, readErr := conn.Read(ctx)
				if readErr != nil {
					cancel()
					log.Fatalln(readErr)
					return
				}
				requestMessage := RequestMessage{}
				err := json.Unmarshal(content, &requestMessage)
				if err != nil {
					err = conn.Write(ctx, websocket.MessageText, []byte("无效的json格式"))
					if err != nil {
						log.Println(err)
					}
					cancel()
					continue
				}
				switch requestMessage.ReceiverType {
				case model.PRIVATE:
					msg, err := model.NewPrivateMessage(requestMessage.Content, requestMessage.SenderId, requestMessage.ReceiverId)
					if err != nil {
						cancel()
						log.Println(err)
						continue
					}
					err = server.MessageSend(ctx, msg)
					if err != nil {
						cancel()
						log.Println(err)
						continue
					}
					err = conn.Write(ctx, websocket.MessageText, []byte("已发送"))
					if err != nil {
						log.Println(err)
					}
					break
				case model.GROUP:
					msg, err := model.NewGroupMessage(requestMessage.Content, requestMessage.SenderId, requestMessage.ReceiverId)
					if err != nil {
						cancel()
						log.Println(err)
						continue
					}
					err = server.MessageSend(ctx, msg)
					if err != nil {
						cancel()
						log.Println(err)
						continue
					}
					err = conn.Write(ctx, websocket.MessageText, []byte("已发送"))
					if err != nil {
						log.Println(err)
					}
					break
				default:
					err = conn.Write(ctx, websocket.MessageText, []byte("未知的消息类型"))
					if err != nil {
						log.Println(err)
					}
					cancel()
					continue
				}
			}
		}(conn)
	})

	if err := http.ListenAndServe(":8888", nil); err != nil {
		log.Fatalln(err)
	}
}
